<?php
require_once(dirname(dirname(__FILE__)) . '/include/def.php');
require_once(INCLUDE_DIR . 'functions.php');
require_once(INCLUDE_DIR . 'HwLoader.class.php');

DEBUG ? error_reporting(E_ALL) && ini_set('display_errors', 'on') : 
				error_reporting(0) && ini_set('display_errors', 'off');

// push 统计页面
Class PStatController {
	const STAT_TYPE_DAY = 1;// 按天统计
	const STAT_TYPE_HOUR = 2;// 按小时统计
	const STAT_TYPE_HALFHOUR = 3;// 按半小时统计

	// 每页显示记录数量默认值
	const DEFAULT_PAGE_SIZE = 50;
	
	// push 主机统计 搜索时段选项
	const SEARCH_DATE_SCOPE_TODAY = 1;// 今天
	const SEARCH_DATE_SCOPE_YESTODAY = 2;// 昨天
	const SEARCH_DATE_SCOPE_THISWEEK = 4;// 本周
	const SEARCH_DATE_SCOPE_THISMONTH = 6;// 本月

	//请源来源 1/导航菜单 2/统计页面链接 3/主机统计页面
	const REQUEST_FROM_LOCAL = 1;
	const REQUEST_FROM_PS = 2;
	const REQUEST_FROM_PHS = 3;
	// 实例引用
	private static $instance = null;
	// 内置变量
	private $variables = array();
	// 模型类
	private $models = array();
	
	// 构造器
	public function __construct()
	{
		$this->init();
	}
	
	// 初始化
	protected function init()
	{
		if (!count($this->variables)) {
			$this->variables = array(
				// 系统标题
				'title' => 'PNCP',
				// 菜单数据
				'menu' => array(
					'ps' => array('title' => 'Push统计数据', 'url' => 'pstat.php?do=ps', 'show' => true),
					'phs' => array('title' => 'Push主机统计数据', 'url' => 'pstat.php?do=phs', 'show' => true),
					//'phsd' => array('title' => 'Push主机实时数据|<span class="sup" title="实时数据">实时</span>|', 'url' => 'pstat.php?do=phsd', 'show' => true),
					'phsd' => array('title' => 'Push主机实时数据', 'url' => 'pstat.php?do=phsd', 'show' => true),
					'sd' => array('title' => 'Push发送记录查询', 'url' => 'pstat.php?do=sd', 'show' => true),
					'rq' => array('title' => 'Push发送结果查询', 'url' => 'pstat.php?do=rq', 'show' => true),
					'pd' => array('title' => '详细内容查询页', 'url' => 'pstat.php?do=pd', 'show' => false),
					'setting' => array('title' => '系统设置', 'url' => 'pstat.php?do=set', 'show' => false)
					),
				// 当前模板路径
				'template_path' => TEMPLATE_DIR . $this->getClassName() . '/',
				// 查询时段超始日期
				'query_min_date' => '2013-6-01',
				// 数据源环境选项
				'env' => array('option' => array('DEV' => '开发环境(DEV)', 'PRO' => '生产环境(PRO)'), 'default' => 'DEV', 'current' => ''),
			);
			
			// 加载model
			$this->loadModels();
		}
	}
	
	// 加载model对象
	protected function loadModels()
	{
		$env = $this->getCurrentEnvVal();
		
		if (!isset($this->models['push']) || !$this->models['push']) {
			$this->models['push'] = Factory::model('Message', array('env' => $env));
		}
	}

	// 设置显示标题
	protected function setTitle($str, $default = false)
	{
		$title = $this->getVar('title');

		$tmpTitle = $str;
		if ($default) {
			// 设置显示标题
			$menus = $this->getVar('menu');
			$tmpTitle = $menus[$this->getVar('action')]['title'];
		}
		
		$title = $tmpTitle . ' - '. $title;
		$this->setVar('title', $title);
	}

	// 设计内置变量
	protected function setVar($key, $value)
	{
		$this->variables[$key] = $value;
	}
	
	// 获取默认页面地址
	protected function getDefaultUrl()
	{
		$menus = array_values($this->getVar('menu'));
		$menuItem = array_shift($menus);
		return $menuItem['url'];
	}
	
	// 获取默认的action名称
	protected function getDefaultAction($fullName = true)
	{
		$menus = array_keys($this->getVar('menu'));
		$name = strtolower(array_shift($menus));
		return $fullName ? $name . 'Action' : $name;
	}
	
	// 获取类名
	protected function getClassName($fullName = false)
	{
		return $fullName ? __CLASS__ : strtolower(substr(__CLASS__, 0, strpos(__CLASS__, 'Controller')));
	}
	
	// 获取action名称
	protected function getActionName($action, $prefix = true)
	{
		return $prefix ? strtolower(substr($action, 0, strpos($action, 'Action'))) : $action;	
	}

	// action参数分解
	protected function dispatch()
	{
		// 接收do参数
		$do = isset($_GET['do']) && strlen($_GET['do']) ? trim($_GET['do']) : '';
		// menu数据
		$menu = $this->getVar('menu');
		$this->setVar('action', strtolower($do));
		// 请求参数无效, 转到默认action
		if (!strlen($this->getVar('action')) || !in_array($this->getVar('action'), array_keys($menu))) {
			/*
			$url = $this->getDefaultUrl();
			header("Location: {$url}");
			return;
			*/
			$this->setVar('action', $this->getDefaultAction(false));
			//die('args error');
		}
		// 动作方法名
		$actionName = strtolower($this->getVar('action')) . 'Action';
		// 控制器类名
		/*
		$controllerName = __CLASS__; 
		$controller = new $controllerName();
		*/
		$data = call_user_func(array($this, $actionName));
		//echo $data;
	}
	
	// 加载模板文件
	protected function template($templateName, $templateVars = null, $templateExt = '.tpl')
	{
		$filename = $templateName . $templateExt;
		
		if (!empty($templateVars)) {
			extract($templateVars);
		}
		
		include $this->getVar('template_path') . $filename;
	}

	// 获取env变量
	protected function getCurrentEnvVal()
	{
		$sessionEnv = $this->sessionData('env_current');
		$envData = $this->getVar('env');

		if (!$envData['current']) {
			$envData['current'] = !is_null($sessionEnv) ? $sessionEnv : $envData['default'];
			$this->setVar('env', $envData);
		}
		return $envData['current'];
	}

	// 获取日期搜索表单所需数据
	protected function getSearchFormData($vars)
	{
		// 日期选项(radio组)数据
		$vars['search_date_option'] = $this->getOptions('FULL_DATE');
		// 产品选项
		$vars['prods'] = $this->getOptions('PROD');
		// 任意月选项
		$vars['ym'] = $this->getOptions('YM');
		
		return $vars;
	}
	
	// 获取Options数据(key => value格式)
	protected function getOptions($type, $params = null) {
		$options = null;
		switch ($type) {
			case 'FULL_DATE' :// 日期选项(radio组)数据
					$options = array (
						'1' => '今天',
						'2' => '昨天',
						'3' => '选择日期',
						'4' => '本周',
						'5' => '上周',
						'6' => '本月',
						'7' => '任意月',
						'8' => '',
			//			'8' => '<a href="#">选择范围</a>',
					);
					break;
			case 'SHORT_DATE' :// 获取选择时段选项(phs页)
					$options = array(
						self::SEARCH_DATE_SCOPE_TODAY => '今天',
					//	self::SEARCH_DATE_SCOPE_YESTODAY => '昨天',
						self::SEARCH_DATE_SCOPE_THISWEEK => '本周',
						self::SEARCH_DATE_SCOPE_THISMONTH => '本月',
					);
					break;
			case 'PROD' :// 产品选项
					$options = $GLOBALS['prods'];
					$options[0] = array( 
						'prod' => 0,
						'name' => '全部产品',
						'type' => '',
						'key'  => '',
						'pw'   => '',
					);
					ksort($options, SORT_NUMERIC);
					break;
			case 'HOST' :
					$options = $this->getHostOptionsByDate($params['start'], $params['end']);
					break;
			case 'YM' :
					// 任意月选项
					// 生成年份, 月份数组
					$queryMaxYM = date('Y-m');
					list($queryMaxYear,) = explode('-', $queryMaxYM);

					$tmpYearData = range(2010, $queryMaxYear);
					$tmpMonthData = range(1, 12);
					$options['query_date_year_option'] = array_combine($tmpYearData, $tmpYearData);
					$options['query_date_month_option'] = array_combine($tmpMonthData, $tmpMonthData);
					break;
			case 'SHOW_TYPE' :
					$options = array('date' => '按日期时间归类', 'host' => '按主机归类');
					break;
				default:
		}

		return $options;
	}

	// hoststr选项
	protected function getHostOptionsByDate($start, $end)
	{
		$hostOptions = array();
		$rows = $this->models['push']->getHostListByDate(array('start' => $start, 'end' => $end));
		if (!empty($rows)) {
			$key = array_search('', $rows);
			if ($key !== false) {// 清除空串数据
				unset($rows[$key]);
			}

			$all = array('' => '全部主机');
			$hostOptions = array_merge($all, $rows);
		}

		return $hostOptions;
	}
	
	// 搜索条件验证
	protected function validateFormBySearchDate(&$msg, &$output = null, &$input = null)
	{
		$now = time();

		// 表单参数默认值
		$default = array(
			'query_date' => 1,
			'prod' => 0,
			'host' => null,
			'query_date_year' => date('Y', $now), 
			'query_date_month' => date('m', $now),
			'show_type' => 'host',
			'start_date' => null,
			'end_date' => null,
		);

		while(1) {
			// 接收表单参数
			$query = array(
				// 日期段类型
				'query_date' => isset($input['query_date']) ? (int)$input['query_date'] : $default['query_date'],
				// 产品id
				'prod' => isset($input['prod']) ? (int)$input['prod'] : $default['prod'],
				// 产品id
				'host' => isset($input['host']) ? trim($input['host']) : $default['host'],
				// 选择日期
				'query_date_calendar' => isset($input['query_date_calendar']) ? trim($input['query_date_calendar']) : null,
				// 年份(选择任意月选项时可选择)
				'query_date_year' => isset($input['query_date_year']) ? trim($input['query_date_year']) : $default['query_date_year'],
				// 月份(选择任意月选项时可选择)
				'query_date_month' => isset($input['query_date_month']) ? trim($input['query_date_month']) : $default['query_date_month'],
				// 显示方式(Push主机统计详细页)
				'show_type' => isset($input['show_type']) ? trim($input['show_type']) : $default['show_type'],
				// 开始日期(Push发送记录查询页)
				'start_date' => isset($input['start_date']) ? trim($input['start_date']) : $default['start_date'],
				// 结束日期(Push发送记录查询页)
				'end_date' => isset($input['end_date']) ? trim($input['end_date']) : $default['end_date'],
			);
			$output['query'] = $query;

			// 参数校验
			if (empty($query['query_date']) || !in_array($query['query_date'], array_keys($output['search_date_option']))) {
				$msg['query_date'] = '时段参数无效';
				break;
			}
			
			// 选择日期校验
			if ($query['query_date'] === 3) {
				// 空值校验
				if (empty($query['query_date_calendar'])) {
					$msg['query_date'] = '时间参数无效(请填写日期)';
					break;
				}
				
				// 日期有效性校验
				list($tmpY, $tmpM, $tmpD) = explode('-', $query['query_date_calendar']);
				if (!checkdate($tmpM, $tmpD, $tmpY)) {
					$msg['query_date'] = '时间参数无效(日期不合法)';
					break;
				}
			}

			// 选择任意月选项时, 检查年月参数(query_date == 7)
			$queryYM = $query['query_date_year'] . '-' . str_pad($query['query_date_month'], 2, '0', STR_PAD_LEFT);
			$queryMinYM = date('Y-m', strtotime($this->getVar('query_min_date')));
			$queryMaxYM = date('Y-m');
			// 验证任意月选项参数
			if ((int)$query['query_date'] === 7) {
				if (empty($query['query_date_year']) || empty($query['query_date_month']) || $queryYM < $queryMinYM ||  $queryYM > $queryMaxYM) {
					$msg['query_date'] = '时段参数无效(该日期不可查询)';
					break;
				}
			}

			// 验证产品id
			if (!strlen($query['prod']) || !in_array($query['prod'], array_keys($output['prods']))) {
				if ($query['prod'] < 0) {
					$msg['prod'] = '产品id参数无效';
					break;	
				}			
			}
		/*
			// host标识校验
			if (!strlen($query['host']) || !in_array($query['host'], array_keys($output['hosts']))) {
				$msg['host'] = '请求参数无效(host)';
				break;			
			}
		*/
			break;
		}

		// 查询字符串
		//$output['qs'] = $_SERVER['QUERY_STRING'];
		$output['qs'] = $this->getQueryString($query);
		return !count($msg) ? true : false;
	}
	
	// 获取查询字符串
	protected function getQueryString($params = array())
	{
		$qs = $_SERVER['QUERY_STRING'];
		if (is_array($params) && !empty($params)) {
			$qsData = array();
			$tmpData = explode('&', $qs);
			if (!empty($tmpData)) {
				foreach ($tmpData as $valString) {
					if (strlen($valString)) {
						list($tmpKey, $tmpVal) = explode('=', $valString);
						if (strlen($tmpKey)) {
							$qsData[$tmpKey] = $tmpVal ;
						}
					}
				}
			}
			$queryParams = array_merge($qsData, $params);
			$qs = http_build_query($queryParams);
		}
		return $qs;
	}
	
	// 获取查询条件(起止日期)
	protected function getSearchDatetime($params)
	{
		// 当前日期
		$now = time(); 
		
		// 查询类别文本
		$dateLabel = null;
		// 默认统计方式
		$statType = self::STAT_TYPE_DAY;
		// 生成查询起止时间段
		$tmpStartDatetime = $tmpEndDatetime = null;
		switch ($params['query_date']) {
			// 今天
			case 1 :
				$dateLabel = '本日';
				$statType = self::STAT_TYPE_HOUR;

				$tmpStartDatetime = strtotime(date('Y-m-d 00:00:00', $now));
				$tmpEndDatetime = strtotime(date('Y-m-d 23:59:59', $now));
				break;
			// 昨天
			case 2 :
				$dateLabel = '昨日';
				$statType = self::STAT_TYPE_HOUR;

				$time = strtotime('-1 day', $now);  
				$tmpStartDatetime = strtotime(date('Y-m-d 00:00:00', $time));
				$tmpEndDatetime = strtotime(date('Y-m-d 23:59:59', $time));
				break;
			// 指定日期
			case 3 :
				list($y, $m, $d) = explode('-', $params['query_date_calendar']);
				$dateLabel = "{$y}年{$m}月{$d}日";
				$statType = self::STAT_TYPE_HOUR;

				$tmpStartDatetime = strtotime($params['query_date_calendar'] .' 00:00:00');
				$tmpEndDatetime =  strtotime($params['query_date_calendar'] .' 23:59:59');
				break;
			// 本周
			case 4 :
				$dateLabel = '本周';
				$time = '1' == date('w') ? strtotime('Monday', $now) : strtotime('last Monday', $now); 
				$tmpStartDatetime = strtotime(date('Y-m-d 00:00:00', $time));  
				$tmpEndDatetime = strtotime(date('Y-m-d 23:59:59', strtotime('Sunday', $now))); 
				break;
			// 上周
			case 5 :
				$dateLabel = '上周';
				// 本周一  
				$thisMonday = '1' == date('w') ? strtotime('Monday', $now) : strtotime('last Monday', $now);  
				// 上周一  
				$lastMonday = strtotime('-7 days', $thisMonday);  
				$tmpStartDatetime = strtotime(date('Y-m-d 00:00:00', $lastMonday)); 
				$tmpEndDatetime = strtotime(date('Y-m-d 23:59:59', strtotime('last sunday', $now)));
				break;
			// 本月
			case 6 :
				$dateLabel = '本月';
				$tmpStartDatetime = mktime(0, 0, 0, date('m', $now), '1', date('Y', $now));
				$tmpEndDatetime = mktime(23, 39, 59, date('m', $now), date('t', $now), date('Y', $now));
				break;
			// 任意月
			case 7 :
				$dateLabel = "{$params['query_date_year']}年{$params['query_date_month']}月";

				$queryYM = $params['query_date_year'] . '-' . $params['query_date_month'];
				$tmpStartDatetime = strtotime(date('Y-m-d 00:00:00', strtotime($queryYM . '-1')));
				// 当月最大天数
				$maxDay = date('t', strtotime($queryYM . '-1'));
				$tmpEndDatetime = strtotime($queryYM . '-' . $maxDay . ' 23:59:59');

				break;
		}
		
		$data =  array('dateLabel' => $dateLabel,
						'start' => $tmpStartDatetime, 
						'end' => $tmpEndDatetime, 
						'statType' => $statType, 
						'prod' => isset($params['prod']) ? $params['prod'] : null);
		if (isset($params['search_host']) && strlen($params['search_host'])) {
			$data['hoststr'] = $params['search_host'];
		}
		
		return $data;
	}
	
	// 检查日期是否合法
	protected function icheckdate($str)
	{
		$tmpDate = explode('-', $str);
		if (count($tmpDate)  < 3) {
			return false;
		}
		
		list($tmpY, $tmpM, $tmpD) = $tmpDate;

		return checkdate($tmpM, $tmpD, $tmpY);
	}

	// 默认页面
	protected function indexAction()
	{
		//echo __FUNCTION__;
	}
	
	// push 统计
	protected function psAction()
	{
		// 设置显示标题
		$this->setTitle(null, true);
		
		// 消息数组
		$msg = array();

		// 设置参数
		$input = $this->getInputParams();
		
		// 输出参数(模板变量)
		$output = array(
			'query' => array(),
		);
		
		$output = $this->getSearchFormData($output);

		while(1) {
			// 搜索表单校验
			$valid = $this->validateFormBySearchDate($msg, $output, $input);
			$query = $output['query'];
			if (!$valid) {
				if (count($msg)) {
					break;
				}
			}
			// 获取查询条件(起止日期)
			// cond['start']/$cond['end']查询时间段: start/起始日期 end/结束日期
			$params = array();
			$tmpKeys = array('query_date', 'query_date_calendar', 'query_date_year', 'query_date_month', 'prod');
			foreach ($tmpKeys as $key) {
				$params[$key] = isset($query[$key]) ? $query[$key] : null;
			}
			// 获取查询条件
			$cond = $this->getSearchDatetime($params);

			// 获取时间段显示文本
			$output['date_label'] = $cond['dateLabel'];
			unset($cond['dateLabel']);

			$query['stat_type'] = $cond['statType'];
			// 显示当前统计的时间段的文本
			$output['stat_time_text'] = date('Y-m-d', $cond['start']) . ' ~ ' . date('Y-m-d', $cond['end']);
			if ($cond['statType'] === self::STAT_TYPE_HOUR) {
				$today = date('Y-m-d');
				if (date('Y-m-d', $cond['start']) === $today) {
					// 当前统计的时间段
					$output['stat_time_text'] = date('Y-m-d', $cond['start']) . ' 00:00:00 ~ now'; 
				} else {
					// 当前某天的时间段
					$output['stat_time_text'] = date('Y-m-d', $cond['start']) . ' 00:00:00 ~ 23:59:59'; 
				}
			}
			$output['hosts'] = array();
			
			$data = array(
				// 获取统计数据
				'list' => $this->models['push']->stat($cond),
			);
			
			if (count($data['list'])) {
				$data['total'] = $this->models['push']->statTotal($cond);
			} else {
				$msg['tips'] = '没有数据';
			}

			//$output['hosts'] = $this->getHostOptionsByDate($cond['start'], $cond['end']);
			
			$output['data'] = $data;

			break;
		}
		
		// 加载模板
		$this->template('ps', compact('msg', 'input', 'output', 'query'));
	}
	
	// Push主机统计
	protected function phsAction()
	{
		// 设置显示标题
		$this->setTitle(null, true);

		// 接收外部参数
		$input = $this->getInputParams();
		$output = array(
			'query'	=> array(),
		);

		while(1) {
			// 参数默认值
			$defaultVals = array(
				'date_scope' => self::SEARCH_DATE_SCOPE_TODAY,
			);

			// 接收外部参数(GET)
			$query = array(
				'date_scope' => isset($input['date_scope']) ? (int)$input['date_scope'] : $defaultVals['date_scope'],
			);

			// 校验参数
			if ($query['date_scope'] < 0 || !in_array($query['date_scope'], array(
												self::SEARCH_DATE_SCOPE_TODAY,
												self::SEARCH_DATE_SCOPE_YESTODAY,
												self::SEARCH_DATE_SCOPE_THISWEEK,
												self::SEARCH_DATE_SCOPE_THISMONTH))) {
				$msg['date_scope'] = '参数无效(date_scope)';
				break;
			}

			// 获取查询条件
			$tmpCond = $this->getSearchDatetime(array('query_date' => $query['date_scope']));
			// 获取时间段显示文本
			$output['date_label'] = $tmpCond['dateLabel'];
			unset($tmpCond['datLabel']);
			// 生成条件
			$cond = array(
				'start' => $tmpCond['start'],
				'end' => $tmpCond['end']
			);
			
			// 生成页面所需变量
			// 选择时段选项
			$output['options']['link']['date_scope'] = array(
				'data' => $this->getOptions('SHORT_DATE'),
				'current' => $query['date_scope'],
				'class' => 'link_selected',
			);
			// 显示当前统计的时间段的文本
			$output['start_date'] = date('Y-m-d', $cond['start']);
			$output['end_date'] = date('Y-m-d', $cond['end']);
			$output['stat_time_text'] = $output['start_date'] . ($output['start_date'] === $output['end_date'] ? '' : ' ~ ' . $output['end_date']);
			
			// 获取查询结果
			// 未处理数量
			$countCond = $cond;
			$countCond['status'] = 0;
			$output['count_pending'] = $this->models['push']->getCount($countCond);
			
			// 获取统计列表数据
			$data = array(
				'list' => $this->models['push']->getStatByHost($cond),
			);
			
			if (count($data['list'])) {// 获取汇总数据
				$data['total'] = $this->models['push']->statTotal($cond);
			} else {
				$msg['tips'] = '没有数据';
			}
		
			// 生成output参数
			$output['data'] = $data;
			
			$output['qs'] = $this->getQueryString($query);
			break;
		}

		// 加载模板
		$this->template('phs', compact('msg', 'input', 'output', 'query'));
	}
	
	// Push主机统计(详细)
	protected function phsdAction()
	{
		// 设置显示标题
		$this->setTitle(null, true);
		
		// 消息数组
		$msg = array();

		// 设置参数
		$input = $this->getInputParams();
		
		// 输出参数(模板变量)
		$output = array(
			'query' => array(),
		);
		
		$output = $this->getSearchFormData($output);

		$output['hosts'] = array();
		$output['showTypes'] = $this->getOptions('SHOW_TYPE');

		while(1) {	
			// 搜索表单校验
			$valid = $this->validateFormBySearchDate($msg, $output, $input);
			$query = $output['query'];
			if (!$valid) {
				if (count($msg)) {
					break;
				}
			}

			// 获取查询条件(起止日期)
			// cond['start']/$cond['end']查询时间段: start/起始日期 end/结束日期
			$params = array();
			$tmpKeys = array('query_date', 'query_date_calendar', 'query_date_year', 'query_date_month', 'prod', 'search_host');
			foreach ($tmpKeys as $key) {
				$params[$key] = isset($query[$key]) ? $query[$key] : null;
			}
			$cond = $this->getSearchDatetime($params);
			// 获取时间段显示文本
			$output['date_label'] = $cond['dateLabel'];
			unset($cond['dateLabel']);

			$cond['showType']  = $query['show_type'];

		//	$query['stat_type'] = $cond['statType'];
			// 显示当前统计的时间段的文本
			$output['stat_time_text'] = date('Y-m-d', $cond['start']) . ' ~ ' . date('Y-m-d', $cond['end']);
			if ($cond['statType'] === self::STAT_TYPE_HOUR) {
				$today = date('Y-m-d');
				if (date('Y-m-d', $cond['start']) === $today) {
					// 当前统计的时间段
					$output['stat_time_text'] = date('Y-m-d', $cond['start']) . ' 00:00:00 ~ now'; 
				} else {
					// 当前某天的时间段
					$output['stat_time_text'] = date('Y-m-d', $cond['start']) . ' 00:00:00 ~ 23:59:59'; 
				}
			}
			
			$data = array(// 获取统计数据
				'list' => $this->models['push']->getStatDetailByHost($cond)
			);

			if (count($data['list'])) {
				$data['total'] = $this->models['push']->statTotal($cond);
			} else {
				$msg['tips'] = '没有数据';
			}
			
			$field = $cond['showType'] == 'host' ? 'hoststr' : 'stat_col';
			$data['count'] = $this->models['push']->iarray_count_values($data['list'], $field);
			
			//$output['hosts'] = $this->getHostOptionsByDate($cond['start'], $cond['end']);

			$output['data'] = $data;

			break;
		}
		
		// 加载模板
		$this->template('phsd', compact('msg', 'input', 'output', 'query'));
	}

	// push 统计详细页
	protected function sdAction()
	{
		// 设置显示标题
		$this->setTitle(null, true);
		
		// 消息数组
		$msg = array();
		// 设置参数
		$input = $this->getInputParams();

		// 输出参数(模板变量)
		$output = array(
			'query' => array(),
		);

		$output = $this->getSearchFormData($output);
		// ??????
		$output['hosts'] = array();
		// 请求来源
		$output['from'] = self::REQUEST_FROM_LOCAL;
		if (isset($input['from']) &&  strlen($input['from']) && in_array((int)$input['from'], array(self::REQUEST_FROM_LOCAL, self::REQUEST_FROM_PS, self::REQUEST_FROM_PHS))) {
			$output['from'] = (int)$input['from'];
		}
		
		while(1) {	
			// 查询条件参数
			$cond = array();

			if ($output['from'] === self::REQUEST_FROM_LOCAL) {// 来源是导航链接
				// 搜索表单校验
				$valid = $this->validateFormBySearchDate($msg, $output, $input);
				$query = $output['query'];
				if (!$valid) {
					if (count($msg)) {
						break;
					}
				}
				
				// 获取查询条件(起止日期)
				// cond['start']/$cond['end']查询时间段: start/起始日期 end/结束日期
				$params = array();
				$tmpKeys = array('query_date', 'query_date_calendar', 'query_date_year', 'query_date_month', 'prod');
				foreach ($tmpKeys as $key) {
					$params[$key] = isset($query[$key]) ? $query[$key] : null;
				}
				// 获取时间段显示文本
				$cond = $this->getSearchDatetime($params);
				$output['date_label'] = $cond['dateLabel'];
				unset($cond['dateLabel']);
			} elseif ($output['from'] === self::REQUEST_FROM_PS) {// 来源是统计页面
				$now = time();
				// 接收请求参数
				$query = array(
					'from' => $output['from'], 
					'search_prod' => isset($input['search_prod']) ? (int)$input['search_prod'] : 0,
					'search_host' => isset($input['search_host']) ? trim($input['search_host']) : null,
					'search_type' => isset($input['search_type']) ? (int)$input['search_type'] : 0,
					'search_date' => isset($input['search_date']) ? trim($input['search_date']) : date('Y-m-d', $now),
					'search_hour' => isset($input['search_hour']) ? (int)$input['search_hour'] : date('H', $now),
					'search_status' => isset($input['search_status']) ? (int)$input['search_status'] : null,
				);
				
				$output['query'] = $query;
				if (get_magic_quotes_gpc()) {
					$output['query'] = array_map ('stripslashes', $output['query']);
				}
				
				// 产品id校验
				if (!strlen($query['search_prod']) || !in_array($query['search_prod'], array_keys($output['prods']))) {
					if ($query['search_prod'] < 0) {
						$msg['search_prod'] = '请求参数无效(产品id)';
						break;	
					}			
				}
	
				// host标识校验
				if (strlen($query['search_host']) && !in_array($query['search_host'], array_keys($output['hosts']))) {
					$msg['search_host'] = '请求参数无效(host)';
					break;			
				}
	
				// 搜索类型空值校验
				if (!$query['search_type'] || !in_array($query['search_type'], array(self::STAT_TYPE_HOUR, self::STAT_TYPE_DAY))) {
					$msg['search_type'] = '请求参数无效(搜索类型)';
					break;
				}
		
				// 发送结果状态校验(-1/发送失败 0/未处理 1/发送成功)
				if (is_null($query['search_status']) || !in_array((int)$query['search_status'], array(1, -1, 0))) {
					$msg['search_status'] = '请求参数无效(发送结果状态不合法)';
					break;
				}

				// 日期空值校验
				if (empty($query['search_date'])) {
					$msg['search_date'] = '请求参数无效(日期)';
					break;
				}
				
				// 日期有效性校验
				list($tmpY, $tmpM, $tmpD) = explode('-', $query['search_date']);
				if (!checkdate($tmpM, $tmpD, $tmpY)) {
					$msg['search_date'] = '请求参数无效(日期不合法)';
					break;
				}
				
				// 查询条件参数(开始/结束)时间
				$start = $end = null;
				if ((int)$query['search_type'] === self::STAT_TYPE_HOUR) {// 如果是时间搜索, 则需小时参数
					// 小时参数校验
					if (!strlen($query['search_hour']) || $query['search_hour'] < 0 || $query['search_hour'] > 23) {
						$msg['search_hour'] = '请求参数无效(时间不合法)';
						break;
					}
			
					$start = strtotime($query['search_date'] . ' ' . $query['search_hour'] . ':00:00');
					$end = strtotime($query['search_date'] . ' ' . $query['search_hour'] . ':59:59');	
				} else {// 按日期搜索
					$start = strtotime($query['search_date'] . ' ' . '00:00:00');
					$end = strtotime($query['search_date'] . ' ' . '23:59:59');
				}

				// 生成查询条件参数
				$cond = array(
					'start' => $start,
					'end' => $end,
					'status' => (int)$query['search_status'],
					'statType' => (int)$query['search_type'],
					'prod' => (int)$query['search_prod']
				);

				if (strlen($query['search_host'])) {
					$cond['hoststr'] = $query['search_host'];
				}

				// 查询字符串
				$output['qs'] = isset($input['qs']) ? $input['qs'] : '?do=ps';
			} elseif ($output['from'] === self::REQUEST_FROM_PHS) {// 来源是PHS主机统计页面
				$now = time();

				// 接收请求参数
				$query = array(
					'from' => $output['from'],
					'query_date' => isset($input['query_date']) ? (int)$input['query_date'] : self::SEARCH_DATE_SCOPE_TODAY,
					'search_prod' => isset($input['search_prod']) ? (int)$input['search_prod'] : 0,
					'search_host' => isset($input['search_host']) ? trim($input['search_host']) : null,
					'search_status' => isset($input['search_status']) ? (int)$input['search_status'] : null,
				);
				
				$output['query'] = $query;
				if (get_magic_quotes_gpc()) {
					$output['query'] = array_map ('stripslashes', $output['query']);
				}
				
				// 产品id校验
				if (!strlen($query['search_prod']) || !in_array($query['search_prod'], array_keys($output['prods']))) {
					if ($query['search_prod'] < 0) {
						$msg['search_prod'] = '请求参数无效(产品id)';
						break;	
					}			
				}
/*
				// host标识校验
				if (strlen($query['search_host']) && !in_array($query['search_host'], array_keys($output['hosts']))) {
					$msg['search_host'] = '请求参数无效(host)';
					break;			
				}
*/	
				// 发送结果状态校验(-1/发送失败 0/未处理 1/发送成功)
				if (is_null($query['search_status']) || !in_array((int)$query['search_status'], array(1, -1, 0))) {
					$msg['search_status'] = '请求参数无效(发送结果状态不合法)';
					break;
				}

				// 查询条件参数
				// cond['start']/$cond['end']查询时间段: start/起始日期 end/结束日期
				$params = array('query_date' => $query['query_date'], 'prod' => $query['search_prod']);
				$cond = $this->getSearchDatetime($params);
				// 获取时间段显示文本
				$output['date_label'] = $cond['dateLabel'];
				unset($cond['dateLabel']);

				$cond['status'] = (int)$query['search_status'];
				if (strlen($query['search_host'])) {
					$cond['hoststr'] = $query['search_host'];
				}

				// 查询字符串
				$output['qs'] = isset($input['qs']) ? $input['qs'] : '';
			} else {
				$msg['from'] = '参数错误(from)';
			}
			
			// 参数错误, break;
			if (count($msg) > 0) {
				break;
			}
			
			// 显示当前统计的时间段的文本
			$output['stat_time_text'] = date('Y-m-d', $cond['start']) . ' ~ ' . date('Y-m-d', $cond['end']);
			if ($cond['statType'] === self::STAT_TYPE_HOUR) {
				$today = date('Y-m-d');
				if (date('Y-m-d', $cond['start']) === $today) {
					// 当前统计的时间段
					$output['stat_time_text'] = date('Y-m-d', $cond['start']) . ' 00:00:00 ~ now'; 
				} else {
					// 当前某天的时间段
					$output['stat_time_text'] = date('Y-m-d', $cond['start']) . ' ' . date('H', $cond['start']) . ':00:00 ~ ' . date('H', $cond['end']) . ':59:59'; 
				}
			}

			// 分页 
			$count = $this->models['push']->getCount($cond);
			$pager = Factory::getPager(array('count' => $count, 'size' => self::DEFAULT_PAGE_SIZE));
			$data = array(
				'list' => $this->models['push']->getList($cond, array('size' => $pager->getSize(), 
																'offset' => $pager->getOffset()))
			);
			$output['data'] = $data;
			$output['page'] = $pager->getHtml();
			
			if (empty($output['data'])) {
				$msg['tips'] = '没有数据';
				break;
			}

			break;
		}

		// 加载模板
		$this->template('sd', compact('msg', 'input', 'output', 'query'));
	}

	// push 发送结果查询页
	protected function rqAction()
	{
		// 设置显示标题
		$this->setTitle(null, true);

		// 消息数组
		$msg = array();
		// 设置参数
		$input = $this->getInputParams();
		
		// 输出参数(模板变量)
		$output = array(
			'query' => array(),
			'prods' => $GLOBALS['prods'],
		);

		while(1) {
			$default = array(
				'field_name' => 'token',
			);

			$query = array(
				'field_name' => isset($input['field_name']) ? trim($input['field_name']) : $default['field_name'],
				'field_value' => isset($input['field_value']) ? trim($input['field_value']) : null,
				'query_date_start' => isset($input['query_date_start']) ? trim($input['query_date_start']) : null,
				'query_date_end' => isset($input['query_date_end']) ? trim($input['query_date_end']) : null,
			);
			
			// 验证表单参数
			if (!strlen($query['field_name']) || !in_array($query['field_name'], array('token', 'mid'))) {
				$msg['field_name'] = '查询列参数无效';
				break;
			}
			
			if (is_null($query['field_value'])) {
				break;
			}
			
			if (!strlen($query['field_value'])) {
				$msg['field_value'] = '查询值无效';
				break;
			}

			//查询条件
			$cond = array();
			// 选择列为token时验证日期
			if ($query['field_name'] === 'token') {
				$result = strlen($query['query_date_start']) && strlen($query['query_date_start']) ? 'ALL' : (strlen($query['query_date_start']) ? 'END_EMPTY' : (strlen($query['query_date_end']) ? 'START_EMPTY' : 'EMPTY'));
				if ($result !== 'EMPTY') {
					if ($result == 'START_EMPTY') {
						$msg['query_date_start'] = '请填写开始日期';
						break;
					} elseif ($result == 'END_EMPTY') {
						$msg['query_date_start'] = '请填写结束日期';
						break;
					} elseif ($result == 'ALL') {
						// 验证开始日期格式
						if (!$this->icheckdate($query['query_date_start'])) {
							$msg['query_date_start'] = '日期参数无效(开始日期不合法)';
							break;
						}

						// 验证结束日期格式
						if (!$this->icheckdate($query['query_date_end'])) {
							$msg['query_date_end'] = '日期参数无效(结束日期不合法)';
							break;
						}
						
						// 验证时间范围
						$startTS = strtotime($query['query_date_start']);
						$endTS = strtotime($query['query_date_end']);
						if ($startTS > $endTS) {
							$msg['query_date_end'] = '开始日期不能大于结束日期';
							break;
						}
							
						// 日期搜索条件
						$cond['start'] = strtotime(date('Y-m-d 00:00:00', $startTS));
						$cond['end'] = strtotime(date('Y-m-d 23:59:59', $endTS));
					}
				}
			}

			$output['query'] = $query;

			// 条件			
			$cond[$query['field_name']] = $query['field_value'];
			// 分页 
			$count = $this->models['push']->getCount($cond);
			$pager = Factory::getPager(array('count' => $count, 'size' => self::DEFAULT_PAGE_SIZE));
			$data = array(
				'list' => $this->models['push']->findByField(
							$cond, 
							array('size' => $pager->getSize(), 'offset' => $pager->getOffset())),
			
			);
			if (count($data['list'])) {
				$data['total'] = $this->models['push']->statTotal($cond);
			} else {
				$msg['tips'] = '没有数据';
			}

			$output['data'] = $data;
			$output['page'] = $pager->getHtml();
			
			break;
		}

		// 加载模板
		$this->template('rq', compact('msg', 'input', 'output', 'query'));
	}	

	// push 详细内容查询页
	protected function pdAction()
	{
		$input = array(
			'id' => isset($_GET['id']) ? $_GET['id'] : 0
		);
		
		if (!$input['id']) {
			die('invalid args');
		}
		
		$row = $this->models['push']->findById($input['id']);
		// 设置显示标题
		$this->setTitle(null, true);
		$this->template('pd', compact('row'));
	}

	// 系统设置
	protected function settingAction()
	{
		$envData = $this->getVar('env');

		$envVal = isset($_GET['env']) ? strtoupper(trim($_GET['env'])) : '';
		if (!strlen($envVal) || !in_array($envVal, array_keys($envData['option']))) {
			die('error: invalid args env');
		}
		
		$envData['current'] = $envVal;
		
		$this->setVar('env', $envData);
		$this->sessionData('env_current', $envVal, true);
		$msg = array(
			'tips' => "数据源成功切换到[{$envData['option'][$envVal]}]"
		);

		$backUrl = $this->getQueryString();
		// 设置显示标题
		$this->setTitle(null, true);
		$this->template('setting', compact('msg', 'env', 'backUrl'));
	}
	
	// 获取请求参数
	protected function getInputParams()
	{
		$input = $_GET;
		if (get_magic_quotes_gpc()) {
			$input = array_map ('stripslashes', $_GET);
		}
		return $input;
	}
	
	// 获取标题
	public function getTitle()
	{
		return $this->getVar('title');
	}

	// 获取内置变量
	public function getVar($key = null)
	{
		if (!strlen($key)) {// 全部
			return $this->variables;
		} else {// 指定key
			return isset($this->variables[$key]) ? $this->variables[$key] : false;		
		}
	}

	// 访问session数据
	public function sessionData($key, $value = null, $isWrite = false)
	{
		// session 
		$tmp = null;

		headers_sent () or session_start ();
		if ($isWrite) {
			$_SESSION[$key] = $value;
		} else {
			$tmp = isset($_SESSION[$key]) ? $_SESSION[$key] : null;
		}
		headers_sent () or session_write_close ();

		return !$isWrite ? $tmp : null;
	}

	// 生成url地址(页面链接使用)
	public function joinUrl($params, $queryString = null)
	{
		if (is_null($queryString)) {
			$queryString = $_SERVER['QUERY_STRING'];
		}

		$qs = null;
		parse_str($queryString, $qs);
		
		$tmp = array();
		if (is_string($params)) {
			parse_str($params, $tmp);
		} elseif (is_array($params)) {
			if (!empty($params)) {
				foreach ($params as $key => $param) {
					if (is_array($param)) {
						array_merge($tmp, $param);
					} else {
						$tmp[$key] = $param;					
					}
				}
			}
		} else {
			// ???
		}
		$qs = array_merge($qs, $tmp);

		return "?" . http_build_query($qs);
	}

	/**
	 * 获取发送结果显示文本
	 */
	public function getSendResult($val, $isText = false)
	{
		// 显示数据
		$data = array(
			'1' => '成功',
			'-1' => '失败',
			'0' => '未处理'
		);

		// 状态
		$status = null;
		if (function_exists('bccomp')) {// 需BCMath扩展
			$status = bccomp($val, 0);
		} else {
			$status = $val + 0 > 0 ?  1 : ($val + 0 < 0 ? -1 : 0);
		}
		
		return $isText ? $data[strval($status)] : $status;
	}
	
	/**
	 * 格式化文本、值
	 */
	public function format($value, $type = 'NULL_TEXT', $default = null)
	{
		$result = null;
		switch (strtoupper($type)) {
			// 标准日期格式
			case 'STD_DATE' :
				$result = date('Y-m-d', $value);
				break;
			// 标准时间格式
			case 'STD_TIME' :
				$result = date('H:i:s', $value);
				break;
			// 标准日期时间格式
			case 'STD_DATETIME' :
				$result = !is_null($value) ? date('Y-m-d H:i:s', $value) : '--';
				break;
			// 时间按小数显示(保留2位小数)
			case 'STD_FLOAT_TIME' : 
				$result = sprintf('%.2fs', $value);
				break;
			// 时间按小数显示(保留4位小数)
			case 'STD_FLOAT_TIME_FULL' : 
				$result = sprintf('%.4fs', $value);
				break;
			// 空项填充文本
			case 'NULL_TEXT' :
				$result = !is_null($value) ? $value : '--';
				break;
			case 'NULL_TEXT_ISSET' :
				if (is_array($value) && !empty($value)) {
					foreach ($value as $key => $name) {
						$data = $$name;
						$result = array_key_exists($data, $key) ?  $data[$key] : '--';
					}
				} else {
					$result = isset($value) ? $$value : '--';
				}
			case 'HOUR_TEXT' :// 格式化小时间显示格式
				$text = $hour = $value;
				if (preg_match("/^\d{1,2}$/", (int)$value) != 0) {
					$text = ($hour . ':00 ~ ' . str_pad((string)(((int)$hour + 1 > 23) ? '00' : ((int)$hour + 1)), 2, '0', STR_PAD_LEFT) . ':00');
				}
				$result = $text;

				break;
			default :
				$result = (is_null($value) || !strlen($value)) ? $default : $value;
				break;
		}

		return $result;
	}
	
	// 获取实例
	public static function getInstance()
	{
		if (self::$instance === null) {
			self::$instance = new self();
		}

		return self::$instance;
    }

	// 执行
	public function run()
	{
		$this->dispatch();
	}
}

// 启动
PStatController::getInstance()->run();